package org.apereo.cas;

import org.apereo.cas.authentication.AuthenticationException;
import org.apereo.cas.authentication.AuthenticationResult;
import org.apereo.cas.authentication.principal.Service;
import org.apereo.cas.logout.LogoutRequest;
import org.apereo.cas.ticket.AbstractTicketException;
import org.apereo.cas.ticket.InvalidTicketException;
import org.apereo.cas.ticket.ServiceTicket;
import org.apereo.cas.ticket.Ticket;
import org.apereo.cas.ticket.TicketGrantingTicket;
import org.apereo.cas.ticket.proxy.ProxyGrantingTicket;
import org.apereo.cas.ticket.proxy.ProxyTicket;
import org.apereo.cas.validation.Assertion;

import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;

/**
 * CAS viewed as a set of services to generate and validate Tickets.
 * 将CAS视为一组服务，用于生成和验证票据
 * <p>
 * This is the interface between a Web HTML, Web Services, RMI, or any other
 * request processing layer and the CAS Service viewed as a mechanism to
 * generate, store, validate, and retrieve Tickets containing Authentication
 * information. The features of the request processing layer (the HttpXXX
 * Servlet objects) are not visible here or in any modules behind this layer. In
 * theory, a standalone application could call these methods directly as a
 * private authentication service.
 * 这是Web HTML、Web服务、RMI或任何其他之间的接口
 * 请求处理层和CAS服务被视为一种机制
 * 生成、存储、验证和检索包含身份验证的票据
 * 信息。请求处理层(HttpXXX)的特性
 * Servlet对象)在此层后的任何模块中都不可见。在
 * 理论上，一个独立的应用程序可以直接调用这些方法
 * 私人身份验证服务。
 * </p>
 *
 * @author William G. Thompson, Jr.
 * @author Dmitry Kopylenko
 * @author Scott Battaglia
 * @author Marvin S. Addison
 * @author Misagh Moayyed
 * @since 3.0.0
 */
public interface CentralAuthenticationService {

    /**
     * CAS namespace.
     */
    String NAMESPACE = CentralAuthenticationService.class.getPackage().getName();

    /**
     * Create a {@link TicketGrantingTicket} by authenticating credentials.
     * The details of the security policy around credential authentication and the definition
     * of authentication success are dependent on the implementation, but it SHOULD be safe to assume
     * that at least one credential MUST be authenticated for ticket creation to succeed.
     *通过认证凭证创建{@link TicketGrantingTicket}。
     * 关于证书认证和定义的安全策略的细节
     * 身份验证的成功与否取决于实现，但是可以安全地假设
     * 必须验证至少一个凭据才能成功创建票据。
     * @param authenticationResult the current authentication result in order to create the ticket.
     * @return Non -null ticket-granting ticket identifier.
     * @throws AuthenticationException on errors authenticating the credentials
     * @throws AbstractTicketException if ticket cannot be created
     */
    TicketGrantingTicket createTicketGrantingTicket(AuthenticationResult authenticationResult)
        throws AuthenticationException, AbstractTicketException;


    /**
     * Updates the ticket instance in the underlying storage mechanism.
     * The properties of a given ticket, such as its authentication attributes
     * may have changed during various legs of the authentication flow.
     *更新底层存储机制中的票据实例。
     * 给定票证的属性，例如它的身份验证属性
     * 在身份验证流的各个分支期间可能发生了更改。
     * @param ticket the ticket
     * @return the updated ticket
     * @since 5.0.0
     */
    Ticket updateTicket(Ticket ticket);

    /**
     * Obtains the given ticket by its id
     * and returns the CAS-representative object. Implementations
     * need to check for the validity of the ticket by making sure
     * it exists and has not expired yet, etc. This method is specifically
     * designed to remove the need to access the ticket registry.
     *通过id获取给定的票据
     * 并返回case - representation对象。实现
     * 需要检查机票的有效性，以确保
     * 它存在并且还没有过期，等等。这种方法特别适用于
     * 旨在消除访问票证注册表的需要。
     * @param ticketId the ticket granting ticket id
     * @return the ticket object
     * @throws InvalidTicketException the invalid ticket exception
     * @since 5.0.0
     */
    Ticket getTicket(String ticketId) throws InvalidTicketException;

    /**
     * Obtains the given ticket by its id and type
     * and returns the CAS-representative object. Implementations
     * need to check for the validity of the ticket by making sure
     * it exists and has not expired yet, etc. This method is specifically
     * designed to remove the need to access the ticket registry.
     * 通过id获取给定的票据
     * 并返回case - representation对象。实现
     * 需要检查机票的有效性，以确保
     * 它存在并且还没有过期，等等。这种方法特别适用于
     * 旨在消除访问票证注册表的需要。
     * @param <T>      the generic ticket type to return that extends {@link Ticket}
     * @param ticketId the ticket granting ticket id
     * @param clazz    the ticket type that is requested to be found
     * @return the ticket object
     * @throws InvalidTicketException the invalid ticket exception
     * @since 4.1.0
     */
    <T extends Ticket> T getTicket(String ticketId, Class<T> clazz) throws InvalidTicketException;

    /**
     * Attempts to delete a ticket from the underlying store
     * and is allowed to run any number of processing on the ticket
     * and removal op before invoking it. The ticket id can be associated
     * with any ticket type that is valid and understood by CAS and the underlying
     * ticket store; however some special cases require that you invoke the appropriate
     * operation when destroying tickets, such {@link #destroyTicketGrantingTicket(String)}.
     *尝试从基础存储区删除票据
     * 并允许对票据运行任意数量的处理
     * 和调用之前的删除操作。可以关联票证id
     * 使用有效且可由CAS和底层用户理解的任何票据类型
     * 票存储;不过，有些特殊情况需要调用适当的方法
     * 操作，如{@link #destroyTicketGrantingTicket(String)}。
     * @param ticketId the ticket id
     */
    default void deleteTicket(String ticketId) {
    }

    /**
     * Retrieve a collection of tickets from the underlying ticket registry.
     * The retrieval operation must pass the predicate check that is solely
     * used to filter the collection of tickets received. Implementations
     * can use the predicate to request a collection of expired tickets,
     * or tickets whose id matches a certain pattern, etc. The resulting
     * collection will include tickets that have been evaluated by the predicate.
     *从基础票证注册表检索票证集合。
     * 检索操作必须通过单独的谓词检查
     * 用于筛选收到的票证集合。实现
     * 可以使用谓词来请求过期票据的集合，
     * 或id匹配特定图案的票，等等。由此产生的
     * 集合将包括已由谓词计算的票据。
     * @param predicate the predicate
     * @return the tickets
     * @since 4.1.0
     */
    Collection<Ticket> getTickets(Predicate<Ticket> predicate);

    /**
     * Grant a {@link ServiceTicket} that may be used to access the given service
     * by authenticating the given credentials.
     * The details of the security policy around credential authentication and the definition
     * of authentication success are dependent on the implementation, but it SHOULD be safe to assume
     * that at least one credential MUST be authenticated for ticket creation to succeed.
     * 授予可用于访问给定服务的{@link ServiceTicket}
     * 通过验证给定的凭据。
     * 关于凭据身份验证和定义的安全策略的详细信息
     * 身份验证的成功与否取决于实现，但应该可以安全地假设
     * 要成功创建票据，至少必须验证一个凭据。
     * <p>
     * The principal that is resolved from the authenticated credentials MUST be the same as that to which
     * the given ticket-granting ticket was issued.
     * 从经过身份验证的凭据解析的主体必须与所解析的主体相同
     * 发给你的准考证发了。
     * </p>
     *
     * @param ticketGrantingTicketId Proof of prior authentication.
     * @param service                The target service of the ServiceTicket.
     * @param authenticationResult   The authentication context established if credentials provided
     * @return Non -null service ticket identifier.
     * @throws AuthenticationException on errors authenticating the credentials
     * @throws AbstractTicketException if the ticket could not be created.
     */
    ServiceTicket grantServiceTicket(String ticketGrantingTicketId, Service service, AuthenticationResult authenticationResult)
        throws AuthenticationException, AbstractTicketException;

    /**
     * Grant a {@link ProxyTicket} that may be used to access the given service
     * by authenticating the given credentials.
     * The details of the security policy around credential authentication and the definition
     * of authentication success are dependent on the implementation, but it SHOULD be safe to assume
     * that at least one credential MUST be authenticated for ticket creation to succeed.
     * 可用于访问给定服务的{ @link ProxyTicket}
     * 通过验证给定的凭证。
     * 关于证书身份验证和定义的安全策略的细节
     * 认证成功依赖于实现,但应该是安全的
     * 至少有一个凭据是为了获得成功而获得认证的。
     * <p>
     * The principal that is resolved from the authenticated credentials MUST be the same as that to which
     * the given ticket-granting ticket was issued.
     * 从经过身份验证的凭据解析的主体必须与所解析的主体相同
     * 发给你的准考证发了。
     * </p>
     *
     * @param proxyGrantingTicket Proof of prior authentication.
     * @param service             The target service of the ServiceTicket.
     * @return Non -null service ticket identifier.
     * @throws AbstractTicketException if the ticket could not be created.
     */
    ProxyTicket grantProxyTicket(String proxyGrantingTicket, Service service) throws AbstractTicketException;

    /**
     * Validate a ServiceTicket for a particular Service.
     * 验证特定服务的ServiceTicket
     * @param serviceTicketId Proof of prior authentication.
     * @param service         Service wishing to validate a prior authentication.
     * @return Non -null ticket validation assertion.
     * @throws AbstractTicketException if there was an error validating the ticket.
     */
    Assertion validateServiceTicket(String serviceTicketId, Service service) throws AbstractTicketException;

    /**
     * Destroy a TicketGrantingTicket and perform back channel logout. This has the effect of invalidating any
     * Ticket that was derived from the TicketGrantingTicket being destroyed. May throw an
     * {@link IllegalArgumentException} if the TicketGrantingTicket ID is null.
     *销毁TicketGrantingTicket并执行回退通道注销。这样做的效果是使任何事情都无效
     * 从被销毁的门票中提取的门票。可能会抛出一个
     * 如果TicketGrantingTicket ID为空，则@link IllegalArgumentException}。
     * @param ticketGrantingTicketId the id of the ticket we want to destroy
     * @return the logout requests.
     */
    List<LogoutRequest> destroyTicketGrantingTicket(String ticketGrantingTicketId);

    /**
     * Delegate(委托委派) a TicketGrantingTicket to a Service for proxying authentication(证明鉴定)
     * to other Services.
     *委托一个TicketGrantingTicket到代理认证的服务对其他服务。
     * @param serviceTicketId      The service ticket identifier that will delegate to a {@link TicketGrantingTicket}.
     * @param authenticationResult The current authentication context before this ticket can be granted.
     * @return Non -null ticket-granting ticket identifier that can grant {@link ServiceTicket} that proxy authentication.
     * @throws AuthenticationException on errors authenticating the credentials
     * @throws AbstractTicketException if there was an error creating the ticket
     */
    ProxyGrantingTicket createProxyGrantingTicket(String serviceTicketId, AuthenticationResult authenticationResult)
        throws AuthenticationException, AbstractTicketException;
}
